import cv2
import numpy as np
from config import logger

class CameraManager:
    def __init__(self):
        # 不在初始化时打开摄像头，只在需要时打开
        self.camera = None
    
    def generate_error_frame(self, message="摄像头不可用"):
        """生成一个带有错误信息的图像帧"""
        # 创建一个黑色背景图像
        img = np.zeros((240, 320, 3), np.uint8)
        
        # 添加错误文本
        font = cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(img, message, (40, 120), font, 0.7, (255, 255, 255), 2)
        
        # 编码为JPEG
        ret, buffer = cv2.imencode('.jpg', img, [cv2.IMWRITE_JPEG_QUALITY, 70])
        return buffer.tobytes()
        
    def generate_frames(self):
        """生成视频帧"""
        # 初始化摄像头
        camera = None
        try:
            logger.info("正在初始化摄像头...")
            camera = cv2.VideoCapture(0)
            if not camera.isOpened():
                logger.error("无法打开摄像头")
                # 生成错误帧而非尝试读取不存在的文件
                error_frame = self.generate_error_frame()
                yield (b'--frame\r\n'
                       b'Content-Type: image/jpeg\r\n\r\n' + error_frame + b'\r\n')
                return
                
            camera.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
            camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
            
            # 设置更低的帧率以减轻带宽压力
            camera.set(cv2.CAP_PROP_FPS, 15)
            
            logger.info("摄像头初始化成功，开始流式传输...")
            
            while True:
                success, frame = camera.read()
                if not success:
                    logger.error("读取摄像头帧失败")
                    # 在读取失败时也提供错误帧
                    error_frame = self.generate_error_frame("读取摄像头失败")
                    yield (b'--frame\r\n'
                           b'Content-Type: image/jpeg\r\n\r\n' + error_frame + b'\r\n')
                    break
                else:
                    # 降低分辨率以提高性能
                    frame = cv2.resize(frame, (320, 240))
                    
                    # 将图像编码为JPEG格式，降低质量以减小数据量
                    ret, buffer = cv2.imencode('.jpg', frame, [cv2.IMWRITE_JPEG_QUALITY, 70])
                    frame = buffer.tobytes()
                    yield (b'--frame\r\n'
                           b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
                
            # 不要在这里使用time.sleep，让它尽可能快地处理帧
        except Exception as e:
            logger.error(f"摄像头处理出错: {str(e)}")
            # 在发生异常时提供错误帧
            error_frame = self.generate_error_frame(f"摄像头错误: {str(e)}")
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + error_frame + b'\r\n')
        finally:
            if camera is not None and camera.isOpened():
                camera.release()
                logger.info("摄像头资源已释放")
